home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / srcuc.zip / UX.C < prev    next >
C/C++ Source or Header  |  1992-02-03  |  12KB  |  554 lines

  1. /* -*-C-*-
  2.  
  3. $Header: /scheme/src/microcode/RCS/ux.c,v 1.10 1992/02/03 23:44:05 jinx Exp $
  4.  
  5. Copyright (c) 1990-1992 Massachusetts Institute of Technology
  6.  
  7. This material was developed by the Scheme project at the Massachusetts
  8. Institute of Technology, Department of Electrical Engineering and
  9. Computer Science.  Permission to copy this software, to redistribute
  10. it, and to use it for any purpose is granted, subject to the following
  11. restrictions and understandings.
  12.  
  13. 1. Any copy made of this software must include this copyright notice
  14. in full.
  15.  
  16. 2. Users of this software agree to make their best efforts (a) to
  17. return to the MIT Scheme project any improvements or extensions that
  18. they make, so that these may be included in future releases; and (b)
  19. to inform MIT of noteworthy uses of this software.
  20.  
  21. 3. All materials developed as a consequence of the use of this
  22. software shall duly acknowledge such use, in accordance with the usual
  23. standards of acknowledging credit in academic research.
  24.  
  25. 4. MIT has made no warrantee or representation that the operation of
  26. this software will be error-free, and MIT is under no obligation to
  27. provide any services, by way of maintenance, update, or otherwise.
  28.  
  29. 5. In conjunction with products arising from the use of this material,
  30. there shall be no use of the name of the Massachusetts Institute of
  31. Technology nor of any adaptation thereof in any advertising,
  32. promotional, or sales literature without prior written consent from
  33. MIT in each case. */
  34.  
  35. #include "ux.h"
  36.  
  37. void
  38. DEFUN (UX_prim_check_errno, (name), enum syscall_names name)
  39. {
  40.   if (errno != EINTR)
  41.     error_system_call (errno, name);
  42.   deliver_pending_interrupts ();
  43. }
  44.  
  45. #ifdef HAVE_TERMIOS
  46.  
  47. int
  48. DEFUN (UX_terminal_get_state, (fd, s), int fd AND Ttty_state * s)
  49. {
  50.   return
  51.     ((((tcgetattr (fd, (& (s -> tio)))) < 0)
  52. #ifdef _HPUX
  53.       || ((UX_ioctl (fd, TIOCGLTC, (& (s -> ltc)))) < 0)
  54. #endif
  55.       ) ? (-1) : 0);
  56. }
  57.  
  58. int
  59. DEFUN (UX_terminal_set_state, (fd, s), int fd AND Ttty_state * s)
  60. {
  61.   return
  62.     ((((tcsetattr (fd, TCSANOW, (& (s -> tio)))) < 0)
  63. #ifdef _HPUX
  64.       || ((UX_ioctl (fd, TIOCSLTC, (& (s -> ltc)))) < 0)
  65. #endif
  66.       ) ? (-1) : 0);
  67. }
  68.  
  69. #else /* not HAVE_TERMIOS */
  70. #ifdef HAVE_TERMIO
  71.  
  72. int
  73. DEFUN (UX_terminal_get_state, (fd, s), int fd AND Ttty_state * s)
  74. {
  75.   return
  76.     ((((UX_ioctl (fd, TCGETA, (& (s -> tio)))) < 0)
  77. #ifdef HAVE_BSD_JOB_CONTROL
  78.       || ((UX_ioctl (fd, TIOCGLTC, (& (s -> ltc)))) < 0)
  79. #endif
  80.       ) ? (-1) : 0);
  81. }
  82.  
  83. int
  84. DEFUN (UX_terminal_set_state, (fd, s), int fd AND Ttty_state * s)
  85. {
  86.   return
  87.     ((((UX_ioctl (fd, TCSETA, (& (s -> tio)))) < 0)
  88. #ifdef HAVE_BSD_JOB_CONTROL
  89.       || ((UX_ioctl (fd, TIOCSLTC, (& (s -> ltc)))) < 0)
  90. #endif
  91.       ) ? (-1) : 0);
  92. }
  93.  
  94. int
  95. DEFUN (UX_tcdrain, (fd), int fd)
  96. {
  97.   return (UX_ioctl (fd, TCSBRK, 1));
  98. }
  99.  
  100. int
  101. DEFUN (UX_tcflush, (fd, queue_selector), int fd AND int queue_selector)
  102. {
  103.   return (UX_ioctl (fd, TCFLSH, queue_selector));
  104. }
  105.  
  106. #else /* not HAVE_TERMIO */
  107.  
  108. #ifdef HAVE_BSD_TTY_DRIVER
  109.  
  110. int
  111. DEFUN (UX_terminal_get_state, (fd, s), int fd AND Ttty_state * s)
  112. {
  113.   return
  114.     ((((UX_ioctl (fd, TIOCGETP, (& (s -> sg)))) < 0)
  115.       || ((UX_ioctl (fd, TIOCGETC, (& (s -> tc)))) < 0)
  116. #ifdef HAVE_BSD_JOB_CONTROL
  117.       || ((UX_ioctl (fd, TIOCGLTC, (& (s -> ltc)))) < 0)
  118. #endif
  119.       || ((UX_ioctl (fd, TIOCLGET, (& (s -> lmode)))) < 0))
  120.      ? (-1) : 0);
  121. }
  122.  
  123. int
  124. DEFUN (UX_terminal_set_state, (fd, s), int fd AND Ttty_state * s)
  125. {
  126.   return
  127.     ((((UX_ioctl (fd, TIOCSETN, (& (s -> sg)))) < 0)
  128.       || ((UX_ioctl (fd, TIOCSETC, (& (s -> tc)))) < 0)
  129. #ifdef HAVE_BSD_JOB_CONTROL
  130.       || ((UX_ioctl (fd, TIOCSLTC, (& (s -> ltc)))) < 0)
  131. #endif
  132.       || ((UX_ioctl (fd, TIOCLSET, (& (s -> lmode)))) < 0))
  133.      ? (-1) : 0);
  134. }
  135.  
  136. int
  137. DEFUN (UX_tcdrain, (fd), int fd)
  138. {
  139.   /* BSD provides no such feature -- pretend it worked. */
  140.   return (0);
  141. }
  142.  
  143. int
  144. DEFUN (UX_tcflush, (fd, queue_selector), int fd AND int queue_selector)
  145. {
  146.   /* Losing BSD always flushes input and output together. */
  147.   int zero = 0;
  148.   return (UX_ioctl (fd, TIOCFLUSH, (&zero)));
  149. }
  150.  
  151. #endif /* HAVE_BSD_TTY_DRIVER */
  152. #endif /* HAVE_TERMIO */
  153. #endif /* HAVE_TERMIOS */
  154.  
  155. #if !defined(_POSIX) && defined(_BSD)
  156.  
  157. pid_t
  158. DEFUN_VOID (UX_getpgrp)
  159. {
  160.   return (getpgrp (getpid ()));
  161. }
  162.  
  163. pid_t
  164. DEFUN_VOID (UX_setsid)
  165. {
  166. #ifdef TIOCNOTTY
  167.   int fd = (UX_open (BSD_DEV_TTY, O_RDWR, 0));
  168.   if (fd >= 0)
  169.     {
  170.       UX_ioctl (fd, TIOCNOTTY, 0);
  171.       UX_close (fd);
  172.     }
  173. #endif
  174.   {
  175.     pid_t pid = (getpid ());
  176.     return (setpgrp (pid, pid));
  177.   }
  178. }
  179.  
  180. #ifndef _SUNOS
  181.  
  182. char *
  183. DEFUN (UX_ctermid, (s), char * s)
  184. {
  185.   static char result [] = BSD_DEV_TTY;
  186.   if (s == 0)
  187.     return (result);
  188.   strcpy (s, BSD_DEV_TTY);
  189.   return (s);
  190. }
  191.  
  192. int
  193. DEFUN (UX_kill, (pid, sig), pid_t pid AND int sig)
  194. {
  195.   return ((pid >= 0) ? (kill (pid, sig)) : (killpg ((-pid), sig)));
  196. }
  197.  
  198. #endif /* not _SUNOS */
  199. #endif /* not _POSIX and _BSD */
  200.  
  201. #ifndef _POSIX
  202. #ifdef HAVE_BSD_JOB_CONTROL
  203.  
  204. pid_t
  205. DEFUN (UX_tcgetpgrp, (fd), int fd)
  206. {
  207.   pid_t pgrp_id;
  208.   return (((UX_ioctl (fd, TIOCGPGRP, (&pgrp_id))) < 0) ? (-1) : pgrp_id);
  209. }
  210.  
  211. int
  212. DEFUN (UX_tcsetpgrp, (fd, pgrp_id),
  213.        int fd AND
  214.        pid_t pgrp_id)
  215. {
  216.   return (UX_ioctl (fd, TIOCSPGRP, (&pgrp_id)));
  217. }
  218.  
  219. #else /* not HAVE_BSD_JOB_CONTROL */
  220.  
  221. pid_t
  222. DEFUN (UX_tcgetpgrp, (fd), int fd)
  223. {
  224.   errno = ENOSYS;
  225.   return (-1);
  226. }
  227.  
  228. int
  229. DEFUN (UX_tcsetpgrp, (fd, pgrp_id),
  230.        int fd AND
  231.        pid_t pgrp_id)
  232. {
  233.   errno = ENOSYS;
  234.   return (-1);
  235. }
  236.  
  237. #endif /* HAVE_BSD_JOB_CONTROL */
  238. #endif /* not _POSIX */
  239.  
  240. #ifdef EMULATE_GETCWD
  241. char *
  242. DEFUN (UX_getcwd, (buffer, length),
  243.        char * buffer AND
  244.        size_t length)
  245. {
  246.   char internal_buffer [MAXPATHLEN + 2];
  247.   char * collection_buffer;
  248.   size_t collection_length;
  249.   if (length <= 0)
  250.     {
  251.       errno = EINVAL;
  252.       return (0);
  253.     }
  254.   /* Allocate the buffer if needed. */
  255.   if (buffer == 0)
  256.     {
  257.       buffer = (UX_malloc (length));
  258.       if (buffer == 0)
  259.     {
  260.       errno = ENOMEM;
  261.       return (0);
  262.     }
  263.     }
  264.   if (length >= (sizeof (internal_buffer)))
  265.     {
  266.       collection_buffer = buffer;
  267.       collection_length = length;
  268.     }
  269.   else
  270.     {
  271.       collection_buffer = internal_buffer;
  272.       collection_length = (sizeof (internal_buffer));
  273.     }
  274. #ifdef HAVE_GETWD
  275.   if ((getwd (collection_buffer)) == 0)
  276.     {
  277.       errno = EACCES;
  278.       return (0);
  279.     }
  280. #else /* not HAVE_GETWD */
  281.   {
  282.     /* Invoke `pwd' and fill the buffer with its output. */
  283.     FILE * stream = (popen ("pwd", "r"));
  284.     char * scan_buffer = collection_buffer;
  285.     if (stream == 0)
  286.       {
  287.     errno = EACCES;
  288.     return (0);
  289.       }
  290.     fgets (collection_buffer, collection_length, stream);
  291.     pclose (stream);
  292.     while (1)
  293.       {
  294.     int c = (*scan_buffer++);
  295.     if (c == '\0')
  296.       break;
  297.     else if (c == '\n')
  298.       {
  299.         (*--scan_buffer) = '\0'; /* remove extraneous newline */
  300.         break;
  301.       }
  302.       }
  303.   }
  304. #endif /* HAVE_GETWD */
  305.   if (collection_buffer == internal_buffer)
  306.     {
  307.       if (length <= (strlen (internal_buffer)))
  308.     {
  309.       errno = ERANGE;
  310.       return (0);
  311.     }
  312.       strcpy (buffer, internal_buffer);
  313.     }
  314.   return (buffer);
  315. }
  316. #endif /* not EMULATE_GETCWD */
  317.  
  318. #ifdef EMULATE_WAITPID
  319. int
  320. DEFUN (UX_waitpid, (pid, stat_loc, options),
  321.        pid_t pid AND
  322.        wait_status_t * stat_loc AND
  323.        int options)
  324. {
  325.   if (pid == (-1))
  326.     return (wait3 (stat_loc, options, 0));
  327. #ifdef HAVE_WAIT4
  328.   else if (pid > 0)
  329.     return (wait4 (pid, stat_loc, options, 0));
  330. #endif
  331.   errno = EINVAL;
  332.   return (-1);
  333. }
  334. #endif /* EMULATE_WAITPID */
  335.  
  336. #ifdef EMULATE_DUP2
  337. int
  338. DEFUN (UX_dup2, (fd, fd2), int fd AND int fd2)
  339. {
  340.   if (fd != fd2)
  341.     UX_close (fd2);
  342.   {
  343.     int result = (UX_fcntl (fd, F_DUPFD, fd2));
  344.     if ((result < 0) && (errno == EINVAL))
  345.       errno = EBADF;
  346.     return (result);
  347.   }
  348. }
  349. #endif /* EMULATE_DUP2 */
  350.  
  351. #ifdef EMULATE_RENAME
  352. int
  353. DEFUN (UX_rename, (from_name, to_name),
  354.        CONST char * from_name AND
  355.        CONST char * to_name)
  356. {
  357.   int result;
  358.   if ((result = (UX_access (from_name, 0))) < 0)
  359.     return (result);
  360.   {
  361.     struct stat fs;
  362.     struct stat ts;
  363.     if (((UX_stat (from_name, (&fs))) == 0) &&
  364.     ((UX_lstat (to_name, (&ts))) == 0))
  365.       {
  366.     if (((fs . st_dev) == (ts . st_dev)) &&
  367.         ((fs . st_ino) == (ts . st_ino)))
  368.       return (0);
  369.     UX_unlink (to_name);
  370.       }
  371.   }
  372.   return
  373.     (((result = (UX_link (from_name, to_name))) < 0)
  374.      ? result
  375.      : (UX_unlink (from_name)));
  376. }
  377. #endif /* EMULATE_RENAME */
  378.  
  379. #ifdef EMULATE_MKDIR
  380. int
  381. DEFUN (UX_mkdir, (name, mode),
  382.        CONST char * name AND
  383.        mode_t mode)
  384. {
  385.   return (UX_mknod (name, ((mode & MODE_DIR) | S_IFDIR), ((dev_t) 0)));
  386. }
  387. #endif /* EMULATE_MKDIR */
  388.  
  389. #ifdef _POSIX
  390.  
  391. cc_t
  392. DEFUN (UX_PC_VDISABLE, (fildes), int fildes)
  393. {
  394.   extern long EXFUN (fpathconf, (int, int));
  395.   long result = (fpathconf (fildes, _PC_VDISABLE));
  396.   return
  397.     ((cc_t) ((result < 0) ?
  398. #ifdef _POSIX_VDISABLE
  399.      _POSIX_VDISABLE
  400. #else
  401.      '\377'
  402. #endif
  403.      : result));
  404. }
  405.  
  406. static clock_t memoized_clk_tck = 0;
  407.  
  408. clock_t
  409. DEFUN_VOID (UX_SC_CLK_TCK)
  410. {
  411.   if (memoized_clk_tck == 0)
  412.     memoized_clk_tck = ((clock_t) (sysconf (_SC_CLK_TCK)));
  413.   return (memoized_clk_tck);
  414. }
  415.  
  416. #endif /* _POSIX */
  417.  
  418. #ifndef _POSIX
  419.  
  420. int
  421. DEFUN (UX_sigemptyset, (set), sigset_t * set)
  422. {
  423.   (*set) = 0;
  424.   return (0);
  425. }
  426.  
  427. int
  428. DEFUN (UX_sigfillset, (set), sigset_t * set)
  429. {
  430.   (*set) = (-1);
  431.   return (0);
  432. }
  433.  
  434. int
  435. DEFUN (UX_sigaddset, (set, signo), sigset_t * set AND int signo)
  436. {
  437.   if (signo <= 0)
  438.     return (-1);
  439.   {
  440.     int mask = (1 << (signo - 1));
  441.     if (mask == 0)
  442.       return (-1);
  443.     (*set) |= mask;
  444.     return (0);
  445.   }
  446. }
  447.  
  448. int
  449. DEFUN (UX_sigdelset, (set, signo), sigset_t * set AND int signo)
  450. {
  451.   if (signo <= 0)
  452.     return (-1);
  453.   {
  454.     int mask = (1 << (signo - 1));
  455.     if (mask == 0)
  456.       return (-1);
  457.     (*set) &=~ mask;
  458.     return (0);
  459.   }
  460. }
  461.  
  462. int
  463. DEFUN (UX_sigismember, (set, signo), CONST sigset_t * set AND int signo)
  464. {
  465.   if (signo <= 0)
  466.     return (-1);
  467.   {
  468.     int mask = (1 << (signo - 1));
  469.     if (mask == 0)
  470.       return (-1);
  471.     return (((*set) & mask) != 0);
  472.   }
  473. }
  474.  
  475. #ifdef HAVE_BSD_SIGNALS
  476.  
  477. #ifdef _HPUX
  478. #define UX_sigvec sigvector
  479. #else
  480. #define UX_sigvec sigvec
  481. #endif
  482.  
  483. #ifndef SV_INTERRUPT
  484. #define SV_INTERRUPT 0
  485. #endif
  486.  
  487. int
  488. DEFUN (UX_sigaction, (signo, act, oact),
  489.        int signo AND
  490.        CONST struct sigaction * act AND
  491.        struct sigaction * oact)
  492. {
  493.   struct sigvec svec;
  494.   struct sigvec sovec;
  495.   struct sigvec * vec = ((act != 0) ? (&svec) : 0);
  496.   struct sigvec * ovec = ((oact != 0) ? (&sovec) : 0);
  497.   if (act != 0)
  498.     {
  499.       (vec -> sv_handler) = (act -> sa_handler);
  500.       (vec -> sv_mask) = (act -> sa_mask);
  501.       (vec -> sv_flags) = SV_INTERRUPT;
  502.     }
  503.   if ((UX_sigvec (signo, vec, ovec)) < 0)
  504.     return (-1);
  505.   if (oact != 0)
  506.     {
  507.       (oact -> sa_handler) = (ovec -> sv_handler);
  508.       (oact -> sa_mask) = (ovec -> sv_mask);
  509.       (oact -> sa_flags) = 0;
  510.     }
  511.   return (0);
  512. }
  513.  
  514. int
  515. DEFUN (UX_sigprocmask, (how, set, oset),
  516.        int how AND
  517.        CONST sigset_t * set AND
  518.        sigset_t * oset)
  519. {
  520.   long omask;
  521.   if (set == 0)
  522.     omask = (sigblock (0));
  523.   else
  524.     switch (how)
  525.       {
  526.       case SIG_BLOCK:
  527.     omask = (sigblock (*set));
  528.     break;
  529.       case SIG_UNBLOCK:
  530.     omask = (sigblock (0));
  531.     if (omask < 0) return (-1);
  532.     omask = (sigsetmask (omask &~ (*set)));
  533.     break;
  534.       case SIG_SETMASK:
  535.     omask = (sigsetmask (*set));
  536.     break;
  537.       default:
  538.     errno = EINVAL;
  539.     return (-1);
  540.       }
  541.   if (omask < 0) return (-1);
  542.   if (oset != 0) (*oset) = omask;
  543.   return (0);
  544. }
  545.  
  546. int
  547. DEFUN (UX_sigsuspend, (set), CONST sigset_t * set)
  548. {
  549.   return (sigpause (*set));
  550. }
  551.  
  552. #endif /* HAVE_BSD_SIGNALS */
  553. #endif /* not _POSIX */
  554.